
#include "vsf_hal.h"

#define APP_USART   vsf_hw_usart1

static volatile bool isDone = false;

static void __usart_tx_isr_handler(void *target_ptr,
                                     vsf_usart_t *usart_ptr,
                                     vsf_usart_irq_mask_t irq_mask)
{
    if (irq_mask & VSF_USART_IRQ_MASK_TX) {
        isDone = true;
    }
}

void vsf_uart_txint_task(void)
{
    uint8_t c = 'a';
    
    vsf_usart_t * usart_ptr = (vsf_usart_t *)&APP_USART;
    
    vsf_usart_cfg_t cfg = {
        .mode = VSF_USART_NO_PARITY | VSF_USART_1_STOPBIT |
                VSF_USART_8_BIT_LENGTH | VSF_USART_NO_HWCONTROL,
        .baudrate   = 115200,
        .rx_timeout = 0,
        .isr =
            {
                .handler_fn = __usart_tx_isr_handler,
                .target_ptr = NULL,
                .prio = vsf_arch_prio_0,
            },
    };
    vsf_usart_init(usart_ptr, &cfg);
    vsf_usart_enable(usart_ptr);
    vsf_usart_irq_enable(usart_ptr, VSF_USART_IRQ_MASK_TX);
    
    while (1) {
        vsf_usart_irq_enable(usart_ptr, VSF_USART_IRQ_MASK_TX);
        while (1 != vsf_usart_txfifo_write(usart_ptr, &c, 1));
        while (!isDone);
        vsf_usart_irq_disable(usart_ptr, VSF_USART_IRQ_MASK_TX);
        isDone = false;

        if (c == 'z') {
            c = 'a';
        } else {
            c++;
        }
    }
}

static void __usart_rx_isr_handler(void *target_ptr,
                                     vsf_usart_t *usart_ptr,
                                     vsf_usart_irq_mask_t irq_mask)
{
    if (irq_mask & VSF_USART_IRQ_MASK_RX) {
        uint8_t c_read;
        while (1 != vsf_usart_rxfifo_read(usart_ptr, &c_read, 1));
        while (1 != vsf_usart_txfifo_write(usart_ptr, &c_read, 1));
    }
}

void vsf_uart_rxint_task(void)
{
    uint8_t c = 'a';
    vsf_usart_t * usart_ptr = (vsf_usart_t *)&APP_USART;

    vsf_usart_cfg_t cfg = {
        .mode = VSF_USART_NO_PARITY | VSF_USART_1_STOPBIT |
                VSF_USART_8_BIT_LENGTH | VSF_USART_NO_HWCONTROL,
        .baudrate   = 115200,
        .rx_timeout = 0,
        .isr =
            {
                .handler_fn = __usart_rx_isr_handler,
                .target_ptr = NULL,
                .prio = vsf_arch_prio_0,
            },
    };
    vsf_usart_init(usart_ptr, &cfg);
    vsf_usart_enable(usart_ptr);
    vsf_usart_irq_enable(usart_ptr, VSF_USART_IRQ_MASK_RX);
}

void vsf_uart_echo_task(void)
{
    uint8_t c_read = 0;
    vsf_usart_t * usart_ptr = (vsf_usart_t *)&APP_USART;

    vsf_usart_cfg_t cfg = {
        .mode = VSF_USART_NO_PARITY | VSF_USART_1_STOPBIT |
                VSF_USART_8_BIT_LENGTH | VSF_USART_NO_HWCONTROL,
        .baudrate   = 115200,
        .rx_timeout = 0,
        .isr =
            {
                .handler_fn = NULL,
                .target_ptr = NULL,
            },
    };
    vsf_usart_init(usart_ptr, &cfg);
    vsf_usart_enable(usart_ptr);

    while (1) {
        if (1 == vsf_usart_rxfifo_read(usart_ptr, &c_read, 1)) {
            while (1 != vsf_usart_txfifo_write(usart_ptr, &c_read, 1));
        }
    }
}

static void __usart_tx_dma_isr_handler(void *target_ptr,
                                       vsf_usart_t *usart_ptr,
                                       vsf_usart_irq_mask_t irq_mask)
{
    if (irq_mask & VSF_USART_IRQ_MASK_TX_CPL) {
        isDone = true;
    }
}

void vsf_uart_dmatx_task(void)
{
    uint8_t c_read = 0;
    
    uint8_t outDataab[128];
	for (int i = 0; i < 128; i++) {
		outDataab[i] = i % 10 + '0';
	}
    
    vsf_usart_t * usart_ptr = (vsf_usart_t *)&APP_USART;

    vsf_usart_cfg_t cfg = {
        .mode = VSF_USART_NO_PARITY | VSF_USART_1_STOPBIT |
                VSF_USART_8_BIT_LENGTH | VSF_USART_NO_HWCONTROL,
        .baudrate   = 115200,
        .rx_timeout = 0,
        .isr =
            {
                .handler_fn = __usart_tx_dma_isr_handler,
                .target_ptr = NULL,
            },
    };
    vsf_usart_init(usart_ptr, &cfg);
    vsf_usart_enable(usart_ptr);
    vsf_usart_irq_enable(usart_ptr, VSF_USART_IRQ_MASK_TX_CPL);

    vsf_err_t err = vsf_usart_request_tx(usart_ptr, outDataab, dimof(outDataab));
    if (err != VSF_ERR_NONE) {
        VSF_ASSERT(0);
    }
    
    while (!isDone);
    
    vsf_usart_irq_disable(usart_ptr, VSF_USART_IRQ_MASK_TX_CPL);
    vsf_usart_disable(usart_ptr);
    vsf_usart_fini(usart_ptr);
}

static void __usart_rx_dma_isr_handler(void *target_ptr,
                                       vsf_usart_t *usart_ptr,
                                       vsf_usart_irq_mask_t irq_mask)
{
    if (irq_mask & VSF_USART_IRQ_MASK_RX_CPL) {
        isDone = true;
    }
}

void vsf_uart_dmarx_task(void)
{
	uint8_t i;
	uint8_t rx_buf[16];
	for (i = 0; i < sizeof(rx_buf); i++) {
        rx_buf[i] = 0;
	}
    
    vsf_usart_t * usart_ptr = (vsf_usart_t *)&APP_USART;

     vsf_usart_cfg_t cfg = {
        .mode = VSF_USART_NO_PARITY | VSF_USART_1_STOPBIT |
                VSF_USART_8_BIT_LENGTH | VSF_USART_NO_HWCONTROL,
        .baudrate   = 115200,
        .rx_timeout = 0,
        .isr =
            {
                .handler_fn = __usart_rx_dma_isr_handler,
                .target_ptr = NULL,
            },
    };
    vsf_usart_init(usart_ptr, &cfg);
    vsf_usart_enable(usart_ptr);
    vsf_usart_irq_enable(usart_ptr, VSF_USART_IRQ_MASK_RX_CPL);

    vsf_err_t err = vsf_usart_request_rx(usart_ptr, rx_buf, dimof(rx_buf));
    if (err != VSF_ERR_NONE) {
        VSF_ASSERT(0);
    }
    
    while (!isDone);
    
    vsf_usart_irq_disable(usart_ptr, VSF_USART_IRQ_MASK_RX_CPL);
    vsf_usart_disable(usart_ptr);
    vsf_usart_fini(usart_ptr);
}
